The questions of the analysis

  1. How do pigs select for anthropogenic forage resources and natural forage resources on the landscape?
  2. How does the selection for anthropogenic forage resources and natural forage resources vary temporally? Can this be described by climatic variables such as snowdepth and temperature?
  3. Do anthropogenic and natural forage resources interact to influence pig movement on a landscape? I.e. when both are present, does the availability of one affect the use of the other?

The goal of this analysis is not to build the best possible model of pig movement on a landscape. Rather, it is to understand how forage resources influence a resource selection in pigs whether this varies in a predictable way between populations.

To answer these questions, we are going to use the framework of continuous-time, discrete-space movement movels described in the previous summary I sent around. The analysis below is performed on 5 populations.

Variable descriptions

The analyses below includes the following covariates. A cell is 30m by 30m.

  1. Correlated random walk (crw): A gradient-response that determines the propensity of a pig to move in the direction that is was moving on it previous move. A positive coefficient indicates that a pig tends to move in the same direction as their previous step.
  2. Canopy cover (canopycover_loc and canopycover_grad): The tree density of a given cell. canopycover_loc is a location-based covariates and a negative coeeficient indicates that as cell cover increases the rate at which a pig leaves that cell decreases (i.e. the time that the pig spends in that cell increases). canopycover_grad is a gradient-based covariate wand a positive coefficient indicates that pigs tend to move in the direction of a increasing canopy cover relative to their current position.
  3. Distance to water (water_loc and water_grad): The distance a pig is from a perennial water source. water_loc is a location-based covariate where a positive coefficient indicates that pigs spend less time in cells that are further from water. water_grad is a gradient-based coefficient where a negative coefficient means that pigs tend to move closer to water.
  4. Distance to crops (crop_loc and crop_grad): Distance to the neareast crop field. crop_loc is a location-based covariate where a positive coefficient indicates that pigs spend less time in cells that are further way from crop fields. crop_grad is a gradient-based covariate where a negative coefficient means that pigs tend to move closer to crop fields.
  5. Masting tree density (masting_loc and masting_grad): The density of masting trees in a cell. masting_loc is a location-based covariate where a negative coefficient indicates that a pig spends more time in a cell with higher masting tree density. masting_grad is a gradient-based covariate where a positive value indicates that pigs move in the direction of higher masting tree density, relative to where they currently are.
  6. NDVI (ndvi_loc and ndvi_grad): A proxy for plant productivity/natural plant forage not a accounted for by masting trees. Varies on a monthly scale. ndvi_loc is a location-based covariate where a negative coefficient indicates that pigs spend more time in cells with higher NDVI. ndvi_grad is a gradient-based covariate where a positive coefficient means that pigs tend to move in the direction of increasing NDVI, relative to where they currently are.
  7. Temperature (temperature_loc): Mean monthly temperature varying by month. Interacts with precipitation, cover, water, and forage covariates.
  8. Precipitation (precipitation_loc): Total monthly precipitation. Interacts with temperature, cover, water, and forage covariates.
  9. Snow depth (snowdepth_loc and snowdepth_grad): Monthly variation in snowdepth at a 1km by 1km scale. snowdepth_loc is a location-based covariate where a positive coeffecient indicates that pigs spend less time in cells with higher snow depth. snowdepth_grad is a gradient-based coefficient where a negative value indicates that pigs tend to move away from increasing snowdepth, relative to their current location.

Of these variables NDVI, Temperature, Precipication, and Snow depth vary monthly, Distance to crops can vary yearly, and Masting tree density, Canopy cover, and distance to water are fixed.

Data summary

Here are some brief summary plots of the populations that are being analyzed. One plot looks at median location of pigs in space and the other gives the break down between male and female pigs in a study.

Analyzing the influence of foraging resources on the movement patterns of pigs

A four step analysis. Each analysis is performed separately for each population.

  1. Analyze a simple main effect model with no interactions
  2. Analyze a GAM model where use of resources varies both daily and monthly
  3. Analyze a main effect model where with monthly and daily variation in movement and interactions between foraging resources.
  4. Analyze a model in which movement varies daily and seasonal variation in foraging is driven by monthly variation in temperature, precipitation, and snowdepth.

Goal: How do anthropogenic (i.e. crops) and natural forage resources affect pig movement, how do these effects vary over time, and how do these effects vary with climatic variables such as temperature and precipitation?

Model 1: Simple main effects model

This model is giving us a sense of overall patterns in how pigs are using foraging resources, cover, and water. Purposefully ignoring a lot of the inherent complexity in this first set of models.

Fit the GLM LASSO model to each dataset

Examine the results of the regularized model fit.

Plot results by coefficient.

tmpdt = list()
for(studynm in names(mod1_betas)){
  
  betas = mod1_betas[[studynm]]
  nms = names(betas)
  dt = data.table(coef=nms, beta=betas, study=studynm)
  tmpdt[[studynm]] = dt
}
mod1betas = do.call(rbind, tmpdt)
ggplot(mod1betas) + geom_point(aes(x=study, y=beta, color=study), size=4) + facet_wrap(~coef,  scales='free') + 
              geom_hline(aes(yintercept=0)) + theme_bw() + theme(axis.text.x = element_text(angle = 90, hjust = 1, size=8))

Summary for Model 1

Consistent effect

  1. canopycover_loc: For all studies, pigs tended to spend more time in higher cover habitat relative to lower cover habitat
  2. canopycover_grad: For all studies, either showed no directional bias or tended to move toward higher cover habitat.
  3. crw: All pigs tended to continue moving in the direction they were previously moving.
  4. sexM: In general, male pigs tend to move faster than female pigs, or show no difference.

Strong, but inconsistent effects

  1. All studies show an effect of crop, but the direction varies among studies. Three studies show that pigs, on average, move slower when they are near crops, but two studies, particularly, Tejon, show that pigs move faster when they are near crops. This could be driven by a single pig in Tejon, will need to account for this.
  2. There is genearlly a strong affect of water_loc, but again this varies by site. 3 of the four sites show that pigs move slower when they are close to water and two sites show slower movement when they are far from water.
  3. NDVI is surprisingly weak for all populations but Tejon.
  4. Masting locations also shows a variable effect across population. No signal in fl_raoul or txcamp, pigs do not linger in masting layers in srel of tx tyler, and pigs stay longer in masting layer in Tejon.

No effects

Many of the gradient effects are unimportant, particularly after accounting for directional persistence.

Model 2: Time-varying analysis for studies

Question: What is the effect of time of day and season on the resource selection of pigs?

  • Not including interactions between resources
  • Not including monthly precipitation and tempurature variables as the montly time variation in resource use should (less mechanistically) account for this
  • Explore daily and monthly changes in resource use. Daily effects: General movement Monthly efects: Canopy cover, forage resources, and distance to water. Note NDVI is already varying by month, so I am not sure it makes a ton of sense to model a time-varying coefficient for this variable. Doing it anyway for now.

Explore the nature of the time-varying effects after LASSO regularization. Extract the betas that minimize CV Deviance.

After regularization, how do these effects vary with time? Let’s look at the daily effect on movement rate first

As expected, all pigs show reduced movement rates at some time of the day, but these effects are not consistent across pig populations. A few populations tend to show reduced movement later in the day, while others show reduced movement around midday.


Now let’s look at how our covariates vary with month.

Some interesting/difficult to interpret population-specific effects

Tejon

There seems to be the strongest temporal variation in resource selection in Tejon pigs.

Some interpretable patterns

  1. During the summer months there is less tendency to move away from crops, though pigs tend to move faster near crops during these months. Not sure how to interpret that.
  2. Pigs move much slower in the masting layer in the winter, fall, and spring months, and do not spend much time in high density masting tree layers in the summer.
  3. Pigs spend much more time in high NDVI cells suring the summer, after accounting for cover.

This seems to be evidence for temporal resource swapping

Camp Bullis

  1. Relatively weak seasonal effects of resource selection

Florida, Raoul

  1. Without error bars this is tough to say, but it looks like over the five months of the study, pigs are selecting for crop resources (spending more time near resources and moving toward these resources) in the early spring with this effect diminishing into May. While the diminishing effect looks quite strong, I am not sure it actually is once we put error bars around this.
  2. Tenatively, it looks like these pigs might be spending more time in high NDVI and high masting density cells once they start leaving crop fields. Again, tough to say here without error bars.

Texas, Tyler w2

  1. No monthly variation in data because we only have two months of data.

SREL contact

  1. Some suggestion for movement toward crops and more time spent near crops in the Fall months.
  2. This corresponds with less time spent in high density masting tree layers and high NDVI layers.

For three out of the 5 studies, there is decent evidence that, as we’d probably expect, pigs are showing temporal shifts between natural resource and anthropogenic resource selection.

Model 3: Interactive effects of resources on pig movement

This model is examining whether the presence of one forage resource effects how pigs use another. Specifically looking for interactions between foraging resources.

In others words, given a pig is in or near a natural or agricultural resource, how does the presence of another resource (or distance to that resource) affect the time the pigs spends in the current resource.

For this analysis, we are going to keep the strong effects of hour and month on general movement patterns, but only consider interactions between static forage resources (i.e. the effects of resources are not time varying).

tmpdt = list()
nm = 15
for(studynm in names(mod3betas)){
  
  betas = mod3betas[[studynm]][1:15]
  nms = names(betas)
  dt = data.table(coef=nms, betas, study=studynm)
  tmpdt[[studynm]] = dt
}
mod3betas_new = do.call(rbind, tmpdt)
ggplot(mod3betas_new) + geom_point(aes(x=study, y=betas, color=study), size=4) + facet_wrap(~coef,  scales='free') + 
              geom_hline(aes(yintercept=0)) + theme_bw() + theme(axis.text.x = element_text(angle = 90, hjust = 1, size=8))

A few interesting interactive effects, but nothing consistent across populations.

  1. In Florida Raoul and Tx Tyler W2 there is an interaction between crop_loc and masting_loc, such that as pigs increase their tendency to spend more time near crops they decrease the time they spend in high masting layers.
  2. For Tejon, there is a positive interaction between NDVI and crop_loc, such that as bigs increase their tendency to spend more time near crops, they spend less time in habitats with high NDVI.

These interactions probably also vary with time. Haven’t looked at that yet.

Step 4: Replacing time-varying parameters with temperature, precipitation, and snow cover interactions

This will be similar to model 2, but instead of basis functions that vary by month (we will keep the daily basis function), we will replace these effect by interactions with temperature and precipitation. This model is trying to get at the mechanistic time varying effects

tmpdt = list()
for(studynm in names(mod3betas)){
  
  betas = mod4betas[[studynm]][1:39]
  nms = names(betas)
  dt = data.table(coef=nms, betas, study=studynm)
  tmpdt[[studynm]] = dt
}
mod4betas_new = do.call(rbind, tmpdt)
ggplot(mod4betas_new) + geom_point(aes(x=study, y=betas, color=study), size=4) + facet_wrap(~coef,  scales='free') + 
              geom_hline(aes(yintercept=0)) + theme_bw() + theme(axis.text.x = element_text(angle = 90, hjust = 1, size=8),
                                                                 strip.text.x = element_text(size = 10))

Consistent Effects

  1. As temperature increases, there is an increased tendency to move toward cover for most studies.
  2. Increasing temperature increases time spent in high NDVI cells
  3. Increased precipitation and temperature generally increases or has no effect on time spend in high masting cells
  4. A consistent effect interaction between temperature and precipitation on water use. Not much to say here other than seasonality, as reflected by this interaction, affect water use.

Plot the temperature, precipitation, and NDVI effects over “month of year” to see how these variables are chaning over the study period.


TODO: Post-hoc population-level analyses

Ok, so we have estimated the effects of various foraging resources on pig movement among different populations, now the goal is to ask what population-level variables (average snow depth, forage resource heterogeneity, ) affect how pig’s use anthropogenic and natural forage resources. Are the consistent population-level or environmental predictors that can account for variation in resource use across populations?

LS0tCnRpdGxlOiAiQW5hbHl6aW5nIHBpZyBtb3ZlbWVudCBhY3Jvc3MgcG9wdWxhdGlvbnMiCmF1dGhvcjogTWFyayBXaWxiZXIgYW5kIFNhcmFoIENoaW5uCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CmJpYmxpb2dyYXBoeTogL1VzZXJzL21xd2lsYmVyL0Ryb3Bib3gvRG9jdW1lbnRzL0JpYmZpbGVzL1Byb2plY3RzX2FuZF9QZXJtaXRzLWZlcmFsX3N3aW5lLmJpYgotLS0KCiMjIFRoZSBxdWVzdGlvbnMgb2YgdGhlIGFuYWx5c2lzCgoxLiBIb3cgZG8gcGlncyBzZWxlY3QgZm9yIGFudGhyb3BvZ2VuaWMgZm9yYWdlIHJlc291cmNlcyBhbmQgbmF0dXJhbCBmb3JhZ2UgcmVzb3VyY2VzIG9uIHRoZSBsYW5kc2NhcGU/CjIuIEhvdyBkb2VzIHRoZSBzZWxlY3Rpb24gZm9yIGFudGhyb3BvZ2VuaWMgZm9yYWdlIHJlc291cmNlcyBhbmQgbmF0dXJhbCBmb3JhZ2UgcmVzb3VyY2VzIHZhcnkgdGVtcG9yYWxseT8gQ2FuIHRoaXMgYmUgZGVzY3JpYmVkIGJ5IGNsaW1hdGljIHZhcmlhYmxlcyBzdWNoIGFzIHNub3dkZXB0aCBhbmQgdGVtcGVyYXR1cmU/IAozLiBEbyBhbnRocm9wb2dlbmljIGFuZCBuYXR1cmFsIGZvcmFnZSByZXNvdXJjZXMgaW50ZXJhY3QgdG8gaW5mbHVlbmNlIHBpZyBtb3ZlbWVudCBvbiBhIGxhbmRzY2FwZT8gSS5lLiB3aGVuIGJvdGggYXJlIHByZXNlbnQsIGRvZXMgdGhlIGF2YWlsYWJpbGl0eSBvZiBvbmUgYWZmZWN0IHRoZSB1c2Ugb2YgdGhlIG90aGVyPwoKVGhlIGdvYWwgb2YgdGhpcyBhbmFseXNpcyBpcyAqKm5vdCoqIHRvIGJ1aWxkIHRoZSBiZXN0IHBvc3NpYmxlIG1vZGVsIG9mIHBpZyBtb3ZlbWVudCBvbiBhIGxhbmRzY2FwZS4gIFJhdGhlciwgaXQgaXMgdG8gdW5kZXJzdGFuZCBob3cgZm9yYWdlIHJlc291cmNlcyBpbmZsdWVuY2UgYSByZXNvdXJjZSBzZWxlY3Rpb24gaW4gcGlncyB3aGV0aGVyIHRoaXMgdmFyaWVzIGluIGEgcHJlZGljdGFibGUgd2F5IGJldHdlZW4gcG9wdWxhdGlvbnMuCgpUbyBhbnN3ZXIgdGhlc2UgcXVlc3Rpb25zLCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHRoZSBmcmFtZXdvcmsgb2YgY29udGludW91cy10aW1lLCBkaXNjcmV0ZS1zcGFjZSBtb3ZlbWVudCBtb3ZlbHMgZGVzY3JpYmVkIGluIHRoZSBwcmV2aW91cyBzdW1tYXJ5IEkgc2VudCBhcm91bmQuIFRoZSBhbmFseXNpcyBiZWxvdyBpcyBwZXJmb3JtZWQgb24gNSBwb3B1bGF0aW9ucy4gCgojIyMgVmFyaWFibGUgZGVzY3JpcHRpb25zCgpUaGUgYW5hbHlzZXMgYmVsb3cgaW5jbHVkZXMgdGhlIGZvbGxvd2luZyBjb3ZhcmlhdGVzLiAgQSBjZWxsIGlzIDMwbSBieSAzMG0uCgoxLiAqQ29ycmVsYXRlZCByYW5kb20gd2FsayogKGBjcndgKTogQSBncmFkaWVudC1yZXNwb25zZSB0aGF0IGRldGVybWluZXMgdGhlIHByb3BlbnNpdHkgb2YgYSBwaWcgdG8gbW92ZSBpbiB0aGUgZGlyZWN0aW9uIHRoYXQgaXMgd2FzIG1vdmluZyBvbiBpdCBwcmV2aW91cyBtb3ZlLiBBIHBvc2l0aXZlIGNvZWZmaWNpZW50IGluZGljYXRlcyB0aGF0IGEgcGlnIHRlbmRzIHRvIG1vdmUgaW4gdGhlIHNhbWUgZGlyZWN0aW9uIGFzIHRoZWlyIHByZXZpb3VzIHN0ZXAuCjIuICpDYW5vcHkgY292ZXIqIChgY2Fub3B5Y292ZXJfbG9jYCBhbmQgYGNhbm9weWNvdmVyX2dyYWRgKTogVGhlIHRyZWUgZGVuc2l0eSBvZiBhIGdpdmVuIGNlbGwuICBgY2Fub3B5Y292ZXJfbG9jYCBpcyBhIGxvY2F0aW9uLWJhc2VkIGNvdmFyaWF0ZXMgYW5kIGEgbmVnYXRpdmUgY29lZWZpY2llbnQgaW5kaWNhdGVzIHRoYXQgYXMgY2VsbCBjb3ZlciBpbmNyZWFzZXMgdGhlIHJhdGUgYXQgd2hpY2ggYSBwaWcgbGVhdmVzIHRoYXQgY2VsbCBkZWNyZWFzZXMgKGkuZS4gdGhlIHRpbWUgdGhhdCB0aGUgcGlnIHNwZW5kcyBpbiB0aGF0IGNlbGwgaW5jcmVhc2VzKS4gYGNhbm9weWNvdmVyX2dyYWRgIGlzIGEgZ3JhZGllbnQtYmFzZWQgY292YXJpYXRlIHdhbmQgYSBwb3NpdGl2ZSBjb2VmZmljaWVudCBpbmRpY2F0ZXMgdGhhdCBwaWdzIHRlbmQgdG8gbW92ZSBpbiB0aGUgZGlyZWN0aW9uIG9mIGEgaW5jcmVhc2luZyBjYW5vcHkgY292ZXIgcmVsYXRpdmUgdG8gdGhlaXIgY3VycmVudCBwb3NpdGlvbi4gCjMuICpEaXN0YW5jZSB0byB3YXRlciogKGB3YXRlcl9sb2NgIGFuZCBgd2F0ZXJfZ3JhZGApOiBUaGUgZGlzdGFuY2UgYSBwaWcgaXMgZnJvbSBhIHBlcmVubmlhbCB3YXRlciBzb3VyY2UuICBgd2F0ZXJfbG9jYCBpcyBhIGxvY2F0aW9uLWJhc2VkIGNvdmFyaWF0ZSB3aGVyZSBhIHBvc2l0aXZlIGNvZWZmaWNpZW50IGluZGljYXRlcyB0aGF0IHBpZ3Mgc3BlbmQgbGVzcyB0aW1lIGluIGNlbGxzIHRoYXQgYXJlIGZ1cnRoZXIgZnJvbSB3YXRlci4gYHdhdGVyX2dyYWRgIGlzIGEgZ3JhZGllbnQtYmFzZWQgY29lZmZpY2llbnQgd2hlcmUgYSBuZWdhdGl2ZSBjb2VmZmljaWVudCBtZWFucyB0aGF0IHBpZ3MgdGVuZCB0byBtb3ZlIGNsb3NlciB0byB3YXRlci4KNC4gKkRpc3RhbmNlIHRvIGNyb3BzKiAoYGNyb3BfbG9jYCBhbmQgYGNyb3BfZ3JhZGApOiBEaXN0YW5jZSB0byB0aGUgbmVhcmVhc3QgY3JvcCBmaWVsZC4gYGNyb3BfbG9jYCBpcyBhIGxvY2F0aW9uLWJhc2VkIGNvdmFyaWF0ZSB3aGVyZSBhIHBvc2l0aXZlIGNvZWZmaWNpZW50IGluZGljYXRlcyB0aGF0IHBpZ3Mgc3BlbmQgbGVzcyB0aW1lIGluIGNlbGxzIHRoYXQgYXJlIGZ1cnRoZXIgd2F5IGZyb20gY3JvcCBmaWVsZHMuICBgY3JvcF9ncmFkYCBpcyBhIGdyYWRpZW50LWJhc2VkIGNvdmFyaWF0ZSB3aGVyZSBhIG5lZ2F0aXZlIGNvZWZmaWNpZW50IG1lYW5zIHRoYXQgcGlncyB0ZW5kIHRvIG1vdmUgY2xvc2VyIHRvIGNyb3AgZmllbGRzLgo1LiAqTWFzdGluZyB0cmVlIGRlbnNpdHkqIChgbWFzdGluZ19sb2NgIGFuZCBgbWFzdGluZ19ncmFkYCk6IFRoZSBkZW5zaXR5IG9mIG1hc3RpbmcgdHJlZXMgaW4gYSBjZWxsLiBgbWFzdGluZ19sb2NgIGlzIGEgbG9jYXRpb24tYmFzZWQgY292YXJpYXRlIHdoZXJlIGEgbmVnYXRpdmUgY29lZmZpY2llbnQgaW5kaWNhdGVzIHRoYXQgYSBwaWcgc3BlbmRzIG1vcmUgdGltZSBpbiBhIGNlbGwgd2l0aCBoaWdoZXIgbWFzdGluZyB0cmVlIGRlbnNpdHkuIGBtYXN0aW5nX2dyYWRgIGlzIGEgZ3JhZGllbnQtYmFzZWQgY292YXJpYXRlIHdoZXJlIGEgcG9zaXRpdmUgdmFsdWUgaW5kaWNhdGVzIHRoYXQgcGlncyBtb3ZlIGluIHRoZSBkaXJlY3Rpb24gb2YgaGlnaGVyIG1hc3RpbmcgdHJlZSBkZW5zaXR5LCByZWxhdGl2ZSB0byB3aGVyZSB0aGV5IGN1cnJlbnRseSBhcmUuCjYuICpORFZJKiAoYG5kdmlfbG9jYCBhbmQgYG5kdmlfZ3JhZGApOiBBIHByb3h5IGZvciBwbGFudCBwcm9kdWN0aXZpdHkvbmF0dXJhbCBwbGFudCBmb3JhZ2Ugbm90IGEgYWNjb3VudGVkIGZvciBieSBtYXN0aW5nIHRyZWVzLiBWYXJpZXMgb24gYSBtb250aGx5IHNjYWxlLiAgYG5kdmlfbG9jYCBpcyBhIGxvY2F0aW9uLWJhc2VkIGNvdmFyaWF0ZSB3aGVyZSBhIG5lZ2F0aXZlIGNvZWZmaWNpZW50IGluZGljYXRlcyB0aGF0IHBpZ3Mgc3BlbmQgbW9yZSB0aW1lIGluIGNlbGxzIHdpdGggaGlnaGVyIE5EVkkuICBgbmR2aV9ncmFkYCBpcyBhIGdyYWRpZW50LWJhc2VkIGNvdmFyaWF0ZSB3aGVyZSBhIHBvc2l0aXZlIGNvZWZmaWNpZW50IG1lYW5zIHRoYXQgcGlncyB0ZW5kIHRvIG1vdmUgaW4gdGhlIGRpcmVjdGlvbiBvZiBpbmNyZWFzaW5nIE5EVkksIHJlbGF0aXZlIHRvIHdoZXJlIHRoZXkgY3VycmVudGx5IGFyZS4KNy4gKlRlbXBlcmF0dXJlKiAoYHRlbXBlcmF0dXJlX2xvY2ApOiBNZWFuIG1vbnRobHkgdGVtcGVyYXR1cmUgdmFyeWluZyBieSBtb250aC4gSW50ZXJhY3RzIHdpdGggcHJlY2lwaXRhdGlvbiwgY292ZXIsIHdhdGVyLCBhbmQgZm9yYWdlIGNvdmFyaWF0ZXMuCjguICpQcmVjaXBpdGF0aW9uKiAoYHByZWNpcGl0YXRpb25fbG9jYCk6IFRvdGFsIG1vbnRobHkgcHJlY2lwaXRhdGlvbi4gIEludGVyYWN0cyB3aXRoIHRlbXBlcmF0dXJlLCBjb3Zlciwgd2F0ZXIsIGFuZCBmb3JhZ2UgY292YXJpYXRlcy4KOS4gKlNub3cgZGVwdGgqIChgc25vd2RlcHRoX2xvY2AgYW5kIGBzbm93ZGVwdGhfZ3JhZGApOiBNb250aGx5IHZhcmlhdGlvbiBpbiBzbm93ZGVwdGggYXQgYSAxa20gYnkgMWttIHNjYWxlLiBgc25vd2RlcHRoX2xvY2AgaXMgYSBsb2NhdGlvbi1iYXNlZCBjb3ZhcmlhdGUgd2hlcmUgYSBwb3NpdGl2ZSBjb2VmZmVjaWVudCBpbmRpY2F0ZXMgdGhhdCBwaWdzIHNwZW5kIGxlc3MgdGltZSBpbiBjZWxscyB3aXRoIGhpZ2hlciBzbm93IGRlcHRoLiAgYHNub3dkZXB0aF9ncmFkYCBpcyBhIGdyYWRpZW50LWJhc2VkIGNvZWZmaWNpZW50IHdoZXJlIGEgbmVnYXRpdmUgdmFsdWUgaW5kaWNhdGVzIHRoYXQgcGlncyB0ZW5kIHRvIG1vdmUgYXdheSBmcm9tIGluY3JlYXNpbmcgc25vd2RlcHRoLCByZWxhdGl2ZSB0byB0aGVpciBjdXJyZW50IGxvY2F0aW9uLgoKT2YgdGhlc2UgdmFyaWFibGVzICpORFZJKiwgKlRlbXBlcmF0dXJlKiwgKlByZWNpcGljYXRpb24qLCBhbmQgKlNub3cgZGVwdGgqIHZhcnkgbW9udGhseSwgKkRpc3RhbmNlIHRvIGNyb3BzKiBjYW4gdmFyeSB5ZWFybHksIGFuZCAqTWFzdGluZyB0cmVlIGRlbnNpdHkqLCAqQ2Fub3B5IGNvdmVyKiwgYW5kICpkaXN0YW5jZSB0byB3YXRlciogYXJlIGZpeGVkLgoKIyMgRGF0YSBzdW1tYXJ5CgpIZXJlIGFyZSBzb21lIGJyaWVmIHN1bW1hcnkgcGxvdHMgb2YgdGhlIHBvcHVsYXRpb25zIHRoYXQgYXJlIGJlaW5nIGFuYWx5emVkLiBPbmUgcGxvdCBsb29rcyBhdCBtZWRpYW4gbG9jYXRpb24gb2YgcGlncyBpbiBzcGFjZSBhbmQgdGhlIG90aGVyIGdpdmVzIHRoZSBicmVhayBkb3duIGJldHdlZW4gbWFsZSBhbmQgZmVtYWxlIHBpZ3MgaW4gYSBzdHVkeS4KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkoZ2xtbmV0KQpsaWJyYXJ5KGZvcmVhY2gpCmxpYnJhcnkoZ2dwbG90MikKcmVxdWlyZShkb01DKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQp0ZWpvbmRhdCA9IGZyZWFkKCIvVXNlcnMvbXF3aWxiZXIvUmVwb3MvcnNmX3N3aW5lL3Jlc3VsdHMvZ2xtZGF0YV9ieV9zdHVkeS90ZWpvbi5jc3YiKQp0eGRhdCA9IGZyZWFkKCIvVXNlcnMvbXF3aWxiZXIvUmVwb3MvcnNmX3N3aW5lL3Jlc3VsdHMvZ2xtZGF0YV9ieV9zdHVkeS90eGNhbXAuY3N2IikKZmxkYXQgPSBmcmVhZCgiL1VzZXJzL21xd2lsYmVyL1JlcG9zL3JzZl9zd2luZS9yZXN1bHRzL2dsbWRhdGFfYnlfc3R1ZHkvZmxfcmFvdWwuY3N2IikKdHh0eWxlcmRhdCA9IGZyZWFkKCIvVXNlcnMvbXF3aWxiZXIvUmVwb3MvcnNmX3N3aW5lL3Jlc3VsdHMvZ2xtZGF0YV9ieV9zdHVkeS90eF90eWxlcl93Mi5jc3YiKQpzcmVsY2RhdCA9IGZyZWFkKCIvVXNlcnMvbXF3aWxiZXIvUmVwb3MvcnNmX3N3aW5lL3Jlc3VsdHMvZ2xtZGF0YV9ieV9zdHVkeS9zcmVsX2NvbnRhY3QuY3N2IikKCgojIEFkZCBpbiBzZXggZGF0YQpwaWdhdHRyaWIgPSBmcmVhZCgifi9SZXBvcy9yc2Zfc3dpbmUvZGF0YS9mb3JtYXR0ZWQvcGlnX2F0dHJpYnV0ZXMuY3N2IilbLCBsaXN0KHBpZ0lELCBzZXgpXQoKIyBDaGVjayBOQSB2YWx1ZXMsIHNob3VsZCBoYXZlIHNvbWUgaW4gdGhlIGNyb3AgdmFsdWVzCnRlam9uZGF0WywgbGFwcGx5KC5TRCwgZnVuY3Rpb24oeCkgYW55KGlzLm5hKHgpKSldWzEsXSA9PSBGQUxTRQp0eGRhdFssIGxhcHBseSguU0QsIGZ1bmN0aW9uKHgpIGFueShpcy5uYSh4KSkpXVsxLCBdID09IEZBTFNFCgojIE1lcmdlIHRoZSBwaWcgYXR0cmlidXRlcyB0byB0aGUgZGF0YQp0ZWpvbmRhdCA9IG1lcmdlKHRlam9uZGF0LCBwaWdhdHRyaWIsIGJ5PSJwaWdJRCIpWyFpcy5uYShuZHZpX2xvYyldCnR4ZGF0ID0gbWVyZ2UodHhkYXQsIHBpZ2F0dHJpYiwgYnk9InBpZ0lEIilbIWlzLm5hKG5kdmlfbG9jKV0KZmxkYXQgPSBtZXJnZShmbGRhdCwgcGlnYXR0cmliLCBieT0icGlnSUQiKVshaXMubmEobmR2aV9sb2MpXQp0eHR5bGVyZGF0ID0gbWVyZ2UodHh0eWxlcmRhdCwgcGlnYXR0cmliLCBieT0icGlnSUQiKVshaXMubmEobmR2aV9sb2MpXQpzcmVsY2RhdCA9IG1lcmdlKHNyZWxjZGF0LCBwaWdhdHRyaWIsIGJ5PSJwaWdJRCIpWyFpcy5uYShuZHZpX2xvYyldCmBgYAoKYGBge3IsIGVjaG89RkFMU0V9CnBpZzEgPSB0ZWpvbmRhdFtwaWdJRCA9PSAidGVqb25NMzAyIl0KCnJlcyA9IGJ1aWxkX2Rlc2lnbl9tYXRyaXgocGlnMSwgYygiY3JvcCIpLCBtb2RlbHR5cGU9Im1haW5fZWZmZWN0cyIpCnBpZzEgPSByZXMkZGF0YQoKZXZhbGZvcm0gPSByZXMkZXZhbGZvcm0KZXZhbGZvcm0gPSB1cGRhdGUuZm9ybXVsYShldmFsZm9ybSwgfiAuIC0gc2V4KQoKWG1hdCA9IG1vZGVsLm1hdHJpeChldmFsZm9ybSwgZGF0YT1waWcxKQoKcmVnaXN0ZXJEb01DKGNvcmVzPTQpCgojIEZpdCBvdmVyYWxsIG1vZGVsIHdpdGggR0xNIExBU1NPCmZpdF9tb2RlbDEgPSBjdi5nbG1uZXQoWG1hdCwgeT1waWcxJHosIG9mZnNldD1sb2cocGlnMSR0YXUpLCBmYW1pbHk9InBvaXNzb24iLCAKICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT0xLCBubGFtYmRhPTIwLCBuZm9sZHM9NCwgcGFyYWxsZWw9VFJVRSkKCgpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQpwbG90KGZpdF9tb2RlbDEpCmZpdF9tb2RlbDEkZ2xtbmV0LmZpdCRiZXRhWywgMTAsIGRyb3A9Rl0KYGBgCgoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNvdXJjZSgicGlnZnhucy5SIikKZGF0YXNldCA9IGxpc3QodHhjYW1wPXR4ZGF0LCB0ZWpvbj10ZWpvbmRhdCwgZmxfcmFvdWw9ZmxkYXQsIHR4X3R5bGVyX3cyPXR4dHlsZXJkYXQsIHNyZWxfY29udGFjdD1zcmVsY2RhdCkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZm9yKHN0dWR5bm0gaW4gbmFtZXMoZGF0YXNldCkpewoKICBkYXQgPSBkYXRhc2V0W1tzdHVkeW5tXV0KICBtZWFuZGF0ID0gZGF0WywgbGlzdChtZWFubGF0PW1lZGlhbih5LmFkaiksIG1lYW5sb249bWVkaWFuKHguYWRqKSwgc2V4PXVuaXF1ZShzZXgpWzFdKSwgYnk9cGlnSURdCiAgcGxvdDEgPSBnZ3Bsb3QobWVhbmRhdCkgKyBnZW9tX3BvaW50KGFlcyh4PW1lYW5sb24sIHk9bWVhbmxhdCwgY29sb3I9cGlnSUQpKSArIHRoZW1lX2J3KCkgKyB4bGFiKCJMb25naXR1ZGUiKSArIHlsYWIoIkxhdGl0dWRlIikgKyBnZ3RpdGxlKHN0dWR5bm0pCiAgcGxvdDIgPSBnZ3Bsb3QobWVhbmRhdCkgKyBnZW9tX2JhcihhZXMoeD1zZXgpKSArIHRoZW1lX2J3KCkgKyBnZ3RpdGxlKHN0dWR5bm0pCiAgcHJpbnQocGxvdDEpCiAgcHJpbnQocGxvdDIpCgp9CmBgYAoKIyBBbmFseXppbmcgdGhlIGluZmx1ZW5jZSBvZiBmb3JhZ2luZyByZXNvdXJjZXMgb24gdGhlIG1vdmVtZW50IHBhdHRlcm5zIG9mIHBpZ3MKCkEgZm91ciBzdGVwIGFuYWx5c2lzLiBFYWNoIGFuYWx5c2lzIGlzIHBlcmZvcm1lZCBzZXBhcmF0ZWx5IGZvciBlYWNoIHBvcHVsYXRpb24uCgoxLiBBbmFseXplIGEgc2ltcGxlIG1haW4gZWZmZWN0IG1vZGVsIHdpdGggbm8gaW50ZXJhY3Rpb25zCjIuIEFuYWx5emUgYSBHQU0gbW9kZWwgd2hlcmUgdXNlIG9mIHJlc291cmNlcyB2YXJpZXMgYm90aCBkYWlseSBhbmQgbW9udGhseQozLiBBbmFseXplIGEgbWFpbiBlZmZlY3QgbW9kZWwgd2hlcmUgd2l0aCBtb250aGx5IGFuZCBkYWlseSB2YXJpYXRpb24gaW4gbW92ZW1lbnQgYW5kIGludGVyYWN0aW9ucyBiZXR3ZWVuIGZvcmFnaW5nIHJlc291cmNlcy4KNC4gQW5hbHl6ZSBhIG1vZGVsIGluIHdoaWNoIG1vdmVtZW50IHZhcmllcyBkYWlseSBhbmQgc2Vhc29uYWwgdmFyaWF0aW9uIGluIGZvcmFnaW5nIGlzIGRyaXZlbiBieSBtb250aGx5IHZhcmlhdGlvbiBpbiB0ZW1wZXJhdHVyZSwgcHJlY2lwaXRhdGlvbiwgYW5kIHNub3dkZXB0aC4KCioqR29hbCoqOiBIb3cgZG8gYW50aHJvcG9nZW5pYyAoaS5lLiBjcm9wcykgYW5kIG5hdHVyYWwgZm9yYWdlIHJlc291cmNlcyBhZmZlY3QgcGlnIG1vdmVtZW50LCBob3cgZG8gdGhlc2UgZWZmZWN0cyB2YXJ5IG92ZXIgdGltZSwgYW5kIGhvdyBkbyB0aGVzZSBlZmZlY3RzIHZhcnkgd2l0aCBjbGltYXRpYyB2YXJpYWJsZXMgc3VjaCBhcyB0ZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbj8KCiMjIyBNb2RlbCAxOiBTaW1wbGUgbWFpbiBlZmZlY3RzIG1vZGVsCgpUaGlzIG1vZGVsIGlzIGdpdmluZyB1cyBhIHNlbnNlIG9mIG92ZXJhbGwgcGF0dGVybnMgaW4gaG93IHBpZ3MgYXJlIHVzaW5nIGZvcmFnaW5nIHJlc291cmNlcywgY292ZXIsIGFuZCB3YXRlci4gUHVycG9zZWZ1bGx5IGlnbm9yaW5nIGEgbG90IG9mIHRoZSBpbmhlcmVudCBjb21wbGV4aXR5IGluIHRoaXMgZmlyc3Qgc2V0IG9mIG1vZGVscy4KCkZpdCB0aGUgR0xNIExBU1NPIG1vZGVsIHRvIGVhY2ggZGF0YXNldAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnJlcXVpcmUoZG9NQykKCmFsbG1vZGVsMV9maXRzID0gbGlzdCgpCmFsbFhzID0gbGlzdCgpCgpmb3Ioc3R1ZHlubSBpbiBuYW1lcyhkYXRhc2V0KSl7CiAgCiAgY2F0KCJGaXR0aW5nIiwgc3R1ZHlubSwgIlxuIikgCiAgZGF0ID0gZGF0YXNldFtbc3R1ZHlubV1dCiAgCiAgIyBGb2xsb3dpbmcgQnVkZXJtYW4gZXQgYWwuIHN0YW5kYXJkaXplIG9uIGEgcGVyIHBpZyBsZXZlbCwgcmF0aGVyIHRoYW4gYWNyb3NzIGFsbCBwaWdzPwogIAogIAogIHJlcyA9IGJ1aWxkX2Rlc2lnbl9tYXRyaXgoZGF0LCBjKCJjcm9wIiksIG1vZGVsdHlwZT0ibWFpbl9lZmZlY3RzIikKICBkYXQgPSByZXMkZGF0YQogIGRhdGFzZXRbW3N0dWR5bm1dXSA9IHJlcyRkYXRhCiAgCiAgZXZhbGZvcm0gPSByZXMkZXZhbGZvcm0KICAKICBYbWF0ID0gbW9kZWwubWF0cml4KGV2YWxmb3JtLCBkYXRhPWRhdCkKICBhbGxYc1tbc3R1ZHlubV1dID0gWG1hdAogIAogIHJlZ2lzdGVyRG9NQyhjb3Jlcz00KQogIAogICMgRml0IG92ZXJhbGwgbW9kZWwgd2l0aCBHTE0gTEFTU08KICBmaXRfbW9kZWwxID0gY3YuZ2xtbmV0KFhtYXQsIHk9ZGF0JHosIG9mZnNldD1sb2coZGF0JHRhdSksIGZhbWlseT0icG9pc3NvbiIsIAogICAgICAgICAgICAgICAgICAgICAgIGFscGhhPTEsIG5sYW1iZGE9MjAsIG5mb2xkcz00LCBwYXJhbGxlbD1UUlVFKQogIGFsbG1vZGVsMV9maXRzW1tzdHVkeW5tXV0gPSBmaXRfbW9kZWwxCn0KYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZndyaXRlKGFzLmRhdGEudGFibGUoYWxsWHNbWyJ0ZWpvbiJdXSksICIuLi9yZXN1bHRzL3RlbXBfWHRlam9uLmNzdiIpCmBgYAoKRXhhbWluZSB0aGUgcmVzdWx0cyBvZiB0aGUgcmVndWxhcml6ZWQgbW9kZWwgZml0LiAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKbW9kMV9iZXRhcyA9IGxpc3QoKQpmb3Ioc3R1ZHlubSBpbiBuYW1lcyhhbGxtb2RlbDFfZml0cykpewogIHRmaXQgPSBhbGxtb2RlbDFfZml0c1tbc3R1ZHlubV1dCiAgIyBwbG90KHRmaXQpCiAgcHJpbnQodGZpdCRnbG1uZXQuZml0JGJldGFbLCB3aGljaCh0Zml0JGxhbWJkYSA9PSB0Zml0JGxhbWJkYS5taW4pLCBkcm9wPUZdKQogIG1vZDFfYmV0YXNbW3N0dWR5bm1dXSA9IHRmaXQkZ2xtbmV0LmZpdCRiZXRhWywgd2hpY2godGZpdCRsYW1iZGEgPT0gdGZpdCRsYW1iZGEuMXNlKSwgZHJvcD1UXQp9CmBgYAoKUGxvdCByZXN1bHRzIGJ5IGNvZWZmaWNpZW50LgoKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQoKdG1wZHQgPSBsaXN0KCkKZm9yKHN0dWR5bm0gaW4gbmFtZXMobW9kMV9iZXRhcykpewogIAogIGJldGFzID0gbW9kMV9iZXRhc1tbc3R1ZHlubV1dCiAgbm1zID0gbmFtZXMoYmV0YXMpCiAgZHQgPSBkYXRhLnRhYmxlKGNvZWY9bm1zLCBiZXRhPWJldGFzLCBzdHVkeT1zdHVkeW5tKQogIHRtcGR0W1tzdHVkeW5tXV0gPSBkdAp9Cgptb2QxYmV0YXMgPSBkby5jYWxsKHJiaW5kLCB0bXBkdCkKZ2dwbG90KG1vZDFiZXRhcykgKyBnZW9tX3BvaW50KGFlcyh4PXN0dWR5LCB5PWJldGEsIGNvbG9yPXN0dWR5KSwgc2l6ZT00KSArIGZhY2V0X3dyYXAofmNvZWYsICBzY2FsZXM9J2ZyZWUnKSArIAogICAgICAgICAgICAgIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQ9MCkpICsgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZT04KSkKCmBgYAoKCioqU3VtbWFyeSBmb3IgTW9kZWwgMSoqCgoqQ29uc2lzdGVudCBlZmZlY3QqCgoxLiBgY2Fub3B5Y292ZXJfbG9jYDogRm9yIGFsbCBzdHVkaWVzLCBwaWdzIHRlbmRlZCB0byBzcGVuZCBtb3JlIHRpbWUgaW4gaGlnaGVyIGNvdmVyIGhhYml0YXQgcmVsYXRpdmUgdG8gbG93ZXIgY292ZXIgaGFiaXRhdAoyLiBgY2Fub3B5Y292ZXJfZ3JhZGA6IEZvciBhbGwgc3R1ZGllcywgZWl0aGVyIHNob3dlZCBubyBkaXJlY3Rpb25hbCBiaWFzIG9yIHRlbmRlZCB0byBtb3ZlIHRvd2FyZCBoaWdoZXIgY292ZXIgaGFiaXRhdC4KMy4gYGNyd2A6ICBBbGwgcGlncyB0ZW5kZWQgdG8gY29udGludWUgbW92aW5nIGluIHRoZSBkaXJlY3Rpb24gdGhleSB3ZXJlIHByZXZpb3VzbHkgbW92aW5nLgo0LiBgc2V4TWA6IEluIGdlbmVyYWwsIG1hbGUgcGlncyB0ZW5kIHRvIG1vdmUgZmFzdGVyIHRoYW4gZmVtYWxlIHBpZ3MsIG9yIHNob3cgbm8gZGlmZmVyZW5jZS4KCgoqU3Ryb25nLCBidXQgaW5jb25zaXN0ZW50IGVmZmVjdHMqCgoxLiBBbGwgc3R1ZGllcyBzaG93IGFuIGVmZmVjdCBvZiBjcm9wLCBidXQgdGhlIGRpcmVjdGlvbiB2YXJpZXMgYW1vbmcgc3R1ZGllcy4gIFRocmVlIHN0dWRpZXMgc2hvdyB0aGF0IHBpZ3MsIG9uIGF2ZXJhZ2UsIG1vdmUgc2xvd2VyIHdoZW4gdGhleSBhcmUgbmVhciBjcm9wcywgYnV0IHR3byBzdHVkaWVzLCBwYXJ0aWN1bGFybHksIFRlam9uLCBzaG93IHRoYXQgcGlncyBtb3ZlIGZhc3RlciB3aGVuIHRoZXkgYXJlIG5lYXIgY3JvcHMuIFRoaXMgY291bGQgYmUgZHJpdmVuIGJ5IGEgc2luZ2xlIHBpZyBpbiBUZWpvbiwgd2lsbCBuZWVkIHRvIGFjY291bnQgZm9yIHRoaXMuIAoyLiBUaGVyZSBpcyBnZW5lYXJsbHkgYSBzdHJvbmcgYWZmZWN0IG9mIGB3YXRlcl9sb2NgLCBidXQgYWdhaW4gdGhpcyB2YXJpZXMgYnkgc2l0ZS4gIDMgb2YgdGhlIGZvdXIgc2l0ZXMgc2hvdyB0aGF0IHBpZ3MgbW92ZSBzbG93ZXIgd2hlbiB0aGV5IGFyZSBjbG9zZSB0byB3YXRlciBhbmQgdHdvIHNpdGVzIHNob3cgc2xvd2VyIG1vdmVtZW50IHdoZW4gdGhleSBhcmUgZmFyIGZyb20gd2F0ZXIuIAozLiBORFZJIGlzIHN1cnByaXNpbmdseSB3ZWFrIGZvciBhbGwgcG9wdWxhdGlvbnMgYnV0IFRlam9uLgo0LiBNYXN0aW5nIGxvY2F0aW9ucyBhbHNvIHNob3dzIGEgdmFyaWFibGUgZWZmZWN0IGFjcm9zcyBwb3B1bGF0aW9uLiAgTm8gc2lnbmFsIGluIGZsX3Jhb3VsIG9yIHR4Y2FtcCwgcGlncyBkbyBub3QgbGluZ2VyIGluIG1hc3RpbmcgbGF5ZXJzIGluIHNyZWwgb2YgdHggdHlsZXIsIGFuZCBwaWdzIHN0YXkgbG9uZ2VyIGluIG1hc3RpbmcgbGF5ZXIgaW4gVGVqb24uCgoqTm8gZWZmZWN0cyoKCk1hbnkgb2YgdGhlIGdyYWRpZW50IGVmZmVjdHMgYXJlIHVuaW1wb3J0YW50LCBwYXJ0aWN1bGFybHkgYWZ0ZXIgYWNjb3VudGluZyBmb3IgZGlyZWN0aW9uYWwgcGVyc2lzdGVuY2UuCgojIyBNb2RlbCAyOiAgVGltZS12YXJ5aW5nIGFuYWx5c2lzIGZvciBzdHVkaWVzCgoqKlF1ZXN0aW9uOioqIFdoYXQgaXMgdGhlIGVmZmVjdCBvZiB0aW1lIG9mIGRheSBhbmQgc2Vhc29uIG9uIHRoZSByZXNvdXJjZSBzZWxlY3Rpb24gb2YgcGlncz8gCgotIE5vdCBpbmNsdWRpbmcgaW50ZXJhY3Rpb25zIGJldHdlZW4gcmVzb3VyY2VzCi0gTm90IGluY2x1ZGluZyBtb250aGx5IHByZWNpcGl0YXRpb24gYW5kIHRlbXB1cmF0dXJlIHZhcmlhYmxlcyBhcyB0aGUgbW9udGx5IHRpbWUgdmFyaWF0aW9uIGluIHJlc291cmNlIHVzZSBzaG91bGQgKGxlc3MgbWVjaGFuaXN0aWNhbGx5KSBhY2NvdW50IGZvciB0aGlzCi0gRXhwbG9yZSBkYWlseSBhbmQgbW9udGhseSBjaGFuZ2VzIGluIHJlc291cmNlIHVzZS4KICAqRGFpbHkgZWZmZWN0cyo6IEdlbmVyYWwgbW92ZW1lbnQKICAqTW9udGhseSBlZmVjdHMqOiBDYW5vcHkgY292ZXIsIGZvcmFnZSByZXNvdXJjZXMsIGFuZCBkaXN0YW5jZSB0byB3YXRlci4gIE5vdGUgTkRWSSBpcyBhbHJlYWR5IHZhcnlpbmcgYnkgbW9udGgsIHNvIEkgYW0gbm90IHN1cmUgaXQgbWFrZXMgYSB0b24gb2Ygc2Vuc2UgdG8gbW9kZWwgYSB0aW1lLXZhcnlpbmcgY29lZmZpY2llbnQgZm9yIHRoaXMgdmFyaWFibGUuIERvaW5nIGl0IGFueXdheSBmb3Igbm93LiAKCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kc291cmNlKCJwaWdmeG5zLlIiKQpkZl9ob3VyID0gNiAjIE51bWJlciBvZiBiYXNpcyB2ZWN0b3JzIGZvciB0aGUgc3BsaW5lcyBmb3IgaG91cgoKIyBBbGxvdyB0aGUgbW9udGhseSBiYXNpcyBmdW5jdGlvbnMgdG8gdmFyeSBiZXR3ZWVuIHN0dWRpZXMgYXMgdGhleSBhcmUgb2YgZGlmZmVyZW50IGxlbmd0aHMuCiMgSWYgYSBzdHVkeSBzcGFucyB0aGUgY291cnNlIG9mIGEgeWVhciwgdXNlIGEgY3ljbGljIHNwbGluZSwgb3RoZXJ3aXNlIHVzZSBhIGN1YmljIHJlZ3Jlc3Npb24gc3BsaW5lCmNjX3llYXIgPSBsaXN0KHR4Y2FtcD1saXN0KEZBTFNFLCAiY3IiLCA2KSwgdGVqb249bGlzdChUUlVFLCAiY2MiLCA2KSwgZmxfcmFvdWw9bGlzdChGQUxTRSwgImNyIiwgNCksIHR4X3R5bGVyX3cyPWMoRkFMU0UsICJjciIsIDEpLCBzcmVsX2NvbnRhY3Q9bGlzdChGQUxTRSwgImNyIiwgNikpCgphbGxtb2RlbDJfZml0cyA9IGxpc3QoKQphbGxYZ2FtcyA9IGxpc3QoKQoKZm9yKHN0dWR5bm0gaW4gbmFtZXMoZGF0YXNldCkpewogIAogIGNhdCgiRml0dGluZyIsIHN0dWR5bm0sICJcbiIpCiAgZGF0ID0gZGF0YXNldFtbc3R1ZHlubV1dCiAgCiAgIyBFeHRyYWN0IGhvdXIgb2YgZGF5IGFuZCBtb250aCBvZiB5ZWFyIGZvciBzcGxpbmUgZml0dGluZwogIGRhdFsgLCBkYXRldGltZTo9YXMuUE9TSVhjdCh0LCBvcmlnaW4gPSAnMTk3MC0wMS0wMScsIHR6ID0gJ0dNVCcpXQogIGRhdFsgLCBob3Vyb2ZkYXk6PWhvdXIoZGF0ZXRpbWUpXQogIGRhdFsgLCBtb250aG9meWVhcjo9bW9udGgoZGF0ZXRpbWUpXQogIAogIFhnYW0gID0gYnVpbGRfZ2FtX2Rlc2lnbl9tYXRyaXgoYWxsWHNbW3N0dWR5bm1dXSwgZGF0LCBjKCIoSW50ZXJjZXB0KSIsICJjcndfeiIsICJzZXhNIiksIGRmX2hvdXI9ZGZfaG91ciwgZGZfbW9udGg9Y2NfeWVhcltbc3R1ZHlubV1dW1szXV0sIGN5Y2xpY195ZWFyPWNjX3llYXJbW3N0dWR5bm1dXVtbMV1dKQogIGFsbFhnYW1zW1tzdHVkeW5tXV0gPSBYZ2FtCiAgCiAgcmVnaXN0ZXJEb01DKGNvcmVzPTQpCiAgZml0bW9kZWwyID0gY3YuZ2xtbmV0KHg9WGdhbSwgeT1kYXQkeiwgb2Zmc2V0PWxvZyhkYXQkdGF1KSwgCiAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT0icG9pc3NvbiIsIGFscGhhPTEsIG5sYW1iZGE9MjAsIG5mb2xkcz00LCBwYXJhbGxlbD1UUlVFKQogIGFsbG1vZGVsMl9maXRzW1tzdHVkeW5tXV0gPSBmaXRtb2RlbDIKfQpgYGAKCkV4cGxvcmUgdGhlIG5hdHVyZSBvZiB0aGUgdGltZS12YXJ5aW5nIGVmZmVjdHMgYWZ0ZXIgTEFTU08gcmVndWxhcml6YXRpb24uICBFeHRyYWN0IHRoZSBiZXRhcyB0aGF0IG1pbmltaXplIENWIERldmlhbmNlLiAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKbW9kZWwyYmV0YXMgPSBsaXN0KCkKZm9yKHN0dWR5bm0gaW4gbmFtZXMoYWxsbW9kZWwyX2ZpdHMpKXsKICAKICB0Zml0ID0gYWxsbW9kZWwyX2ZpdHNbW3N0dWR5bm1dXQogICNwbG90KHRmaXQpCiAgbW9kZWwyYmV0YXNbW3N0dWR5bm1dXSA9IHRmaXQkZ2xtbmV0LmZpdCRiZXRhWywgd2hpY2godGZpdCRsYW1iZGEgPT0gdGZpdCRsYW1iZGEubWluKSwgZHJvcD1UXQp9CmBgYAoKQWZ0ZXIgcmVndWxhcml6YXRpb24sIGhvdyBkbyB0aGVzZSBlZmZlY3RzIHZhcnkgd2l0aCB0aW1lPyAgTGV0J3MgbG9vayBhdCB0aGUgZGFpbHkgZWZmZWN0IG9uIG1vdmVtZW50IHJhdGUgZmlyc3QKCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShnZ3Bsb3QyKQoKYWxsZGFpbHkgPSBsaXN0KCkKZm9yKHN0dWR5bm0gaW4gbmFtZXMoZGF0YXNldCkpewogIAogIGRhdCA9IGRhdGFzZXRbW3N0dWR5bm1dXQogIHNwbGluZWhvdXIgPSBzKGhvdXJvZmRheSwgYnM9ImNjIiwgaz1kZl9ob3VyKQogIHByZWRfaG91cnMgPSBQcmVkaWN0Lm1hdHJpeChzbW9vdGguY29uc3RydWN0MihzcGxpbmVob3VyLCBkYXQsIE5VTEwpLCBkYXRhLmZyYW1lKGhvdXJvZmRheT0wOjIzKSkgIyBCLXNwbGluZSBiYXNpcyBmb3IgaG91ciBlZmZlY3QKICBiZXN0YmV0YXMgPSBtb2RlbDJiZXRhc1tbc3R1ZHlubV1dCiAgCiAgZGFpbHlyZXMgPSBsaXN0KCkKICBmb3IocGF0dGVybiBpbiBjKCJob3VyXyoiKSl7CiAgICAKICAgIGVmZiA9IHByZWRfaG91cnMgJSolIHQodChiZXN0YmV0YXNbbmFtZXMoYmVzdGJldGFzKSAlbGlrZSUgcGF0dGVybl0pKQogICAgZWZmZHQgPSBkYXRhLmZyYW1lKGhvdXI9MDoyMywgYmV0YT1lZmYsIGNvZWY9cGF0dGVybikKICAgIGRhaWx5cmVzW1twYXR0ZXJuXV0gPSBlZmZkdAogIH0KICAKICBkYWlseXJlcyA9IGRvLmNhbGwocmJpbmQsIGRhaWx5cmVzKQogIGRhaWx5cmVzJHN0dWR5ID0gc3R1ZHlubQogIGFsbGRhaWx5W1tzdHVkeW5tXV0gPSBkYWlseXJlcwogIHRwbG90ID0gZ2dwbG90KGRhaWx5cmVzKSArIGdlb21fbGluZShhZXMoeD1ob3VyLCB5PWJldGEpKSArIHhsYWIoIkhvdXIgb2YgZGF5IikgKyB5bGFiKCJFZmZlY3Qgb24gaG91cmx5IG1vdmVtZW50IHJhdGUiKSArIHRoZW1lX2J3KCkgKyBmYWNldF93cmFwKH5jb2VmKSArIGdndGl0bGUoc3R1ZHlubSkKICBwcmludCh0cGxvdCkKICAKfQoKYWxsZGFpbHkgPSBkby5jYWxsKHJiaW5kLCBhbGxkYWlseSkKZ2dwbG90KGFsbGRhaWx5KSArIGdlb21fbGluZShhZXMoeD1ob3VyLCB5PWJldGEsIGNvbG9yPXN0dWR5KSkgKyB4bGFiKCJIb3VyIG9mIGRheSIpICsgeWxhYigiRWZmZWN0IG9uIGhvdXJseSBtb3ZlbWVudCByYXRlIikgKyB0aGVtZV9idygpICsgZmFjZXRfd3JhcCh+Y29lZikgKyBnZ3RpdGxlKCJDb21iaW5lZCIpCgoKCmBgYAoKCkFzIGV4cGVjdGVkLCBhbGwgcGlncyBzaG93IHJlZHVjZWQgbW92ZW1lbnQgcmF0ZXMgYXQgc29tZSB0aW1lIG9mIHRoZSBkYXksIGJ1dCB0aGVzZSBlZmZlY3RzIGFyZSBub3QgY29uc2lzdGVudCBhY3Jvc3MgcGlnIHBvcHVsYXRpb25zLiAgQSBmZXcgcG9wdWxhdGlvbnMgdGVuZCB0byBzaG93IHJlZHVjZWQgbW92ZW1lbnQgbGF0ZXIgaW4gdGhlIGRheSwgd2hpbGUgb3RoZXJzIHNob3cgcmVkdWNlZCBtb3ZlbWVudCBhcm91bmQgbWlkZGF5LgoKLS0tCgpOb3cgbGV0J3MgbG9vayBhdCBob3cgb3VyIGNvdmFyaWF0ZXMgdmFyeSB3aXRoIG1vbnRoLgoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgphbGxtb250aHJlcyA9IGxpc3QoKQpmb3Ioc3R1ZHlubSBpbiBuYW1lcyhkYXRhc2V0KSl7CiAgCiAgZGF0ID0gZGF0YXNldFtbc3R1ZHlubV1dCiAgCiAgbWF4ZGZtb250aCA9IGlmZWxzZShjY195ZWFyW1tzdHVkeW5tXV1bWzNdXSA9PSAxLCAyLCBjY195ZWFyW1tzdHVkeW5tXV1bWzNdXSkKICBzcGxpbmVtb250aCA9IHMobW9udGhvZnllYXIsIGJzPWNjX3llYXJbW3N0dWR5bm1dXVtbMl1dLCBrPWlmZWxzZShjY195ZWFyW1tzdHVkeW5tXV1bWzFdXSwgbWF4ZGZtb250aCwgbWF4ZGZtb250aCAgLSAxKSkKICAKICBtaW5tb250aCA9IG1pbihkYXQkbW9udGhvZnllYXIpCiAgbWF4bW9udGggPSBtYXgoZGF0JG1vbnRob2Z5ZWFyKQogIAogIGlmKGNjX3llYXJbW3N0dWR5bm1dXVtbM11dID4gMSkKICAgIHByZWRfbW9udGhzID0gUHJlZGljdC5tYXRyaXgoc21vb3RoLmNvbnN0cnVjdDIoc3BsaW5lbW9udGgsIGRhdCwgTlVMTCksIGRhdGEuZnJhbWUobW9udGhvZnllYXI9c2VxKG1pbm1vbnRoLCBtYXhtb250aCwgbGVuPTIwKSkpCiAgZWxzZQogICAgcHJlZF9tb250aHMgPSB0KHQocmVwKDEsIDIwKSkpCiAgYmVzdGJldGFzID0gbW9kZWwyYmV0YXNbW3N0dWR5bm1dXQogIAogIG1vbnRocmVzID0gbGlzdCgpCiAgZm9yKHBhdHRlcm4gaW4gYygiY292ZXJfbG9jXyoiLCAiY292ZXJfZ3JhZF8qIiwgImNyb3BfZ3JhZF8qIiwgImNyb3BfbG9jXyoiLCAid2F0ZXJfbG9jXyoiLCAid2F0ZXJfZ3JhZF8qIiwKICAgICAgICAgICAgICAgICAibW9udGhfKiIsICJtYXN0aW5nX2xvY18qIiwgIm1hc3RpbmdfZ3JhZF8qIiwgIm5kdmlfbG9jXyoiLCAibmR2aV9ncmFkXyoiKSl7CiAgICAKICAgIGVmZiA9IHByZWRfbW9udGhzICUqJSB0KHQoYmVzdGJldGFzW25hbWVzKGJlc3RiZXRhcykgJWxpa2UlIHBhdHRlcm5dKSkKICAgIGVmZmR0ID0gZGF0YS5mcmFtZShtb250aD1zZXEobWlubW9udGgsIG1heG1vbnRoLCBsZW49MjApLCBiZXRhPWVmZiwgY29lZj1wYXR0ZXJuKQogICAgbW9udGhyZXNbW3BhdHRlcm5dXSA9IGVmZmR0CiAgfQogIAogIG1vbnRocmVzID0gZG8uY2FsbChyYmluZCwgbW9udGhyZXMpCiAgbW9udGhyZXMkc3R1ZHkgPSBzdHVkeW5tCiAgYWxsbW9udGhyZXNbW3N0dWR5bm1dXSA9IG1vbnRocmVzCiAgdHBsb3QgPSBnZ3Bsb3QobW9udGhyZXMpICsgZ2VvbV9saW5lKGFlcyh4PW1vbnRoLCB5PWJldGEpKSArIHhsYWIoIk1vbnRoIG9mIHllYXIiKSArIAogICAgICAgICAgICAgICAgICB5bGFiKCJFZmZlY3Qgb24gbW92ZW1lbnQgcmF0ZSIpICsgdGhlbWVfYncoKSArIGZhY2V0X3dyYXAofmNvZWYsIHNjYWxlcz0iZnJlZSIpICsgZ2d0aXRsZShzdHVkeW5tKQogIHByaW50KHRwbG90KQogIAp9CgphbGxtb250aHJlcyA9IGRvLmNhbGwocmJpbmQsIGFsbG1vbnRocmVzKQp0cGxvdCA9IGdncGxvdChhbGxtb250aHJlcykgKyBnZW9tX2xpbmUoYWVzKHg9bW9udGgsIHk9YmV0YSwgY29sb3I9c3R1ZHkpKSArIHhsYWIoIk1vbnRoIG9mIHllYXIiKSArIAogICAgICAgICAgICAgICAgICB5bGFiKCJFZmZlY3Qgb24gbW92ZW1lbnQgcmF0ZSIpICsgdGhlbWVfYncoKSArIGZhY2V0X3dyYXAofmNvZWYsIHNjYWxlcz0iZnJlZSIpICsgZ2d0aXRsZShzdHVkeW5tKQpwcmludCh0cGxvdCkKCmBgYAoKClNvbWUgaW50ZXJlc3RpbmcvZGlmZmljdWx0IHRvIGludGVycHJldCBwb3B1bGF0aW9uLXNwZWNpZmljIGVmZmVjdHMKCioqVGVqb24qKgoKVGhlcmUgc2VlbXMgdG8gYmUgdGhlIHN0cm9uZ2VzdCB0ZW1wb3JhbCB2YXJpYXRpb24gaW4gcmVzb3VyY2Ugc2VsZWN0aW9uIGluIFRlam9uIHBpZ3MuIAoKU29tZSBpbnRlcnByZXRhYmxlIHBhdHRlcm5zCgoxLiBEdXJpbmcgdGhlIHN1bW1lciBtb250aHMgdGhlcmUgaXMgbGVzcyB0ZW5kZW5jeSB0byBtb3ZlIGF3YXkgZnJvbSBjcm9wcywgdGhvdWdoIHBpZ3MgdGVuZCB0byBtb3ZlIGZhc3RlciBuZWFyIGNyb3BzIGR1cmluZyB0aGVzZSBtb250aHMuIE5vdCBzdXJlIGhvdyB0byBpbnRlcnByZXQgdGhhdC4KMi4gUGlncyBtb3ZlIG11Y2ggc2xvd2VyIGluIHRoZSBtYXN0aW5nIGxheWVyIGluIHRoZSB3aW50ZXIsIGZhbGwsIGFuZCBzcHJpbmcgbW9udGhzLCBhbmQgZG8gbm90IHNwZW5kIG11Y2ggdGltZSBpbiBoaWdoIGRlbnNpdHkgbWFzdGluZyB0cmVlIGxheWVycyBpbiB0aGUgc3VtbWVyLgozLiBQaWdzIHNwZW5kIG11Y2ggbW9yZSB0aW1lIGluIGhpZ2ggTkRWSSBjZWxscyBzdXJpbmcgdGhlIHN1bW1lciwgYWZ0ZXIgYWNjb3VudGluZyBmb3IgY292ZXIuCgpUaGlzIHNlZW1zIHRvIGJlIGV2aWRlbmNlIGZvciB0ZW1wb3JhbCByZXNvdXJjZSBzd2FwcGluZwoKKipDYW1wIEJ1bGxpcyoqCgoxLiBSZWxhdGl2ZWx5IHdlYWsgc2Vhc29uYWwgZWZmZWN0cyBvZiByZXNvdXJjZSBzZWxlY3Rpb24KCioqRmxvcmlkYSwgUmFvdWwqKgoKMS4gV2l0aG91dCBlcnJvciBiYXJzIHRoaXMgaXMgdG91Z2ggdG8gc2F5LCBidXQgaXQgbG9va3MgbGlrZSBvdmVyIHRoZSBmaXZlIG1vbnRocyBvZiB0aGUgc3R1ZHksIHBpZ3MgYXJlIHNlbGVjdGluZyBmb3IgY3JvcCByZXNvdXJjZXMgKHNwZW5kaW5nIG1vcmUgdGltZSBuZWFyIHJlc291cmNlcyBhbmQgbW92aW5nIHRvd2FyZCB0aGVzZSByZXNvdXJjZXMpIGluIHRoZSBlYXJseSBzcHJpbmcgd2l0aCB0aGlzIGVmZmVjdCBkaW1pbmlzaGluZyBpbnRvIE1heS4gV2hpbGUgdGhlIGRpbWluaXNoaW5nIGVmZmVjdCBsb29rcyBxdWl0ZSBzdHJvbmcsIEkgYW0gbm90IHN1cmUgaXQgYWN0dWFsbHkgaXMgb25jZSB3ZSBwdXQgZXJyb3IgYmFycyBhcm91bmQgdGhpcy4KMi4gVGVuYXRpdmVseSwgaXQgbG9va3MgbGlrZSB0aGVzZSBwaWdzIG1pZ2h0IGJlIHNwZW5kaW5nIG1vcmUgdGltZSBpbiBoaWdoIE5EVkkgYW5kIGhpZ2ggbWFzdGluZyBkZW5zaXR5IGNlbGxzIG9uY2UgdGhleSBzdGFydCBsZWF2aW5nIGNyb3AgZmllbGRzLiBBZ2FpbiwgdG91Z2ggdG8gc2F5IGhlcmUgd2l0aG91dCBlcnJvciBiYXJzLgoKKipUZXhhcywgVHlsZXIgdzIqKgoKMS4gTm8gbW9udGhseSB2YXJpYXRpb24gaW4gZGF0YSBiZWNhdXNlIHdlIG9ubHkgaGF2ZSB0d28gbW9udGhzIG9mIGRhdGEuCgoqKlNSRUwgY29udGFjdCoqCgoxLiBTb21lIHN1Z2dlc3Rpb24gZm9yIG1vdmVtZW50IHRvd2FyZCBjcm9wcyBhbmQgbW9yZSB0aW1lIHNwZW50IG5lYXIgY3JvcHMgaW4gdGhlIEZhbGwgbW9udGhzLgoyLiBUaGlzIGNvcnJlc3BvbmRzIHdpdGggbGVzcyB0aW1lIHNwZW50IGluIGhpZ2ggZGVuc2l0eSBtYXN0aW5nIHRyZWUgbGF5ZXJzIGFuZCBoaWdoIE5EVkkgbGF5ZXJzLgoKRm9yIHRocmVlIG91dCBvZiB0aGUgNSBzdHVkaWVzLCB0aGVyZSBpcyBkZWNlbnQgZXZpZGVuY2UgdGhhdCwgYXMgd2UnZCBwcm9iYWJseSBleHBlY3QsIHBpZ3MgYXJlIHNob3dpbmcgdGVtcG9yYWwgc2hpZnRzIGJldHdlZW4gbmF0dXJhbCByZXNvdXJjZSBhbmQgYW50aHJvcG9nZW5pYyByZXNvdXJjZSBzZWxlY3Rpb24uIAoKIyMgTW9kZWwgMzogSW50ZXJhY3RpdmUgZWZmZWN0cyBvZiByZXNvdXJjZXMgb24gcGlnIG1vdmVtZW50CgpUaGlzIG1vZGVsIGlzIGV4YW1pbmluZyB3aGV0aGVyIHRoZSBwcmVzZW5jZSBvZiBvbmUgZm9yYWdlIHJlc291cmNlIGVmZmVjdHMgaG93IHBpZ3MgdXNlIGFub3RoZXIuICBTcGVjaWZpY2FsbHkgbG9va2luZyBmb3IgaW50ZXJhY3Rpb25zIGJldHdlZW4gZm9yYWdpbmcgcmVzb3VyY2VzLgoKSW4gb3RoZXJzIHdvcmRzLCBnaXZlbiBhIHBpZyBpcyBpbiBvciBuZWFyIGEgbmF0dXJhbCBvciBhZ3JpY3VsdHVyYWwgcmVzb3VyY2UsIGhvdyBkb2VzIHRoZSBwcmVzZW5jZSBvZiBhbm90aGVyIHJlc291cmNlIChvciBkaXN0YW5jZSB0byB0aGF0IHJlc291cmNlKSBhZmZlY3QgdGhlIHRpbWUgdGhlIHBpZ3Mgc3BlbmRzIGluIHRoZSBjdXJyZW50IHJlc291cmNlLgoKRm9yIHRoaXMgYW5hbHlzaXMsIHdlIGFyZSBnb2luZyB0byBrZWVwIHRoZSBzdHJvbmcgZWZmZWN0cyBvZiBob3VyIGFuZCBtb250aCBvbiBnZW5lcmFsIG1vdmVtZW50IHBhdHRlcm5zLCBidXQgb25seSBjb25zaWRlciBpbnRlcmFjdGlvbnMgYmV0d2VlbiBzdGF0aWMgZm9yYWdlIHJlc291cmNlcyAoaS5lLiB0aGUgZWZmZWN0cyBvZiByZXNvdXJjZXMgYXJlIG5vdCB0aW1lIHZhcnlpbmcpLiAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpzb3VyY2UoInBpZ2Z4bnMuUiIpCgphbGxtb2RlbDNfZml0cyA9IGxpc3QoKQphbGxYaW50cyA9IGxpc3QoKQoKZm9yKHN0dWR5bm0gaW4gbmFtZXMoZGF0YXNldCkpewogIAogIGNhdCgiRml0dGluZyIsIHN0dWR5bm0sICJcbiIpCiAgCiAgZGF0ID0gZGF0YXNldFtbc3R1ZHlubV1dCiAgaW50ZXIgPSBidWlsZF9kZXNpZ25fbWF0cml4KGRhdCwgYygiY3JvcCIpLCBtb2RlbHR5cGUgPSAiaW50ZXJhY3Rpb25zIikKICBkYXRhc2V0W1tzdHVkeW5tXV0gPSBpbnRlciRkYXRhCiAgZXZhbGZvcm0gPSBpbnRlciRldmFsZm9ybQogIAogIFhnYW0gPSBhbGxYZ2Ftc1tbc3R1ZHlubV1dCiAgCiAgbWF4ZGZtb250aCA9IGlmZWxzZShjY195ZWFyW1tzdHVkeW5tXV1bWzNdXSA9PSAxLCAyLCBjY195ZWFyW1tzdHVkeW5tXV1bWzNdXSkKICBYaW50ID0gY2JpbmQobW9kZWwubWF0cml4KGV2YWxmb3JtLCBpbnRlciRkYXRhKSwgWGdhbVssIGMocGFzdGUwKCJob3VyXyIsIDE6KGRmX2hvdXIgLSAxKSksIHBhc3RlMCgibW9udGhfIiwgMToobWF4ZGZtb250aCAtIDEpKSldKQogIGFsbFhpbnRzW1tzdHVkeW5tXV0gPSBYaW50CiAgCiAgZml0bW9kZWwzID0gY3YuZ2xtbmV0KFhpbnQsIHk9ZGF0JHosIG9mZnNldD1sb2coZGF0JHRhdSksIAogICAgICAgICAgICAgICAgICAgIGZhbWlseT0icG9pc3NvbiIsIGFscGhhPTEsIG5sYW1iZGE9MjAsIG5mb2xkcz00LCBwYXJhbGxlbD1UUlVFKQogIGFsbG1vZGVsM19maXRzW1tzdHVkeW5tXV0gPSBmaXRtb2RlbDMKICAKfQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKbW9kM2JldGFzID0gbGlzdCgpCmZvcihzdHVkeW5tIGluIG5hbWVzKGFsbG1vZGVsM19maXRzKSl7CiAgCiAgdGZpdCA9IGFsbG1vZGVsM19maXRzW1tzdHVkeW5tXV0KICAjcGxvdCh0Zml0KQogIHByaW50KHN0dWR5bm0pCiAgcHJpbnQodGZpdCRnbG1uZXQuZml0JGJldGFbLCB3aGljaCh0Zml0JGxhbWJkYSA9PSB0Zml0JGxhbWJkYS4xc2UpLCBkcm9wPUZdKQogIG1vZDNiZXRhc1tbc3R1ZHlubV1dID0gdGZpdCRnbG1uZXQuZml0JGJldGFbLCB3aGljaCh0Zml0JGxhbWJkYSA9PSB0Zml0JGxhbWJkYS4xc2UpLCBkcm9wPVRdCn0KYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwfQp0bXBkdCA9IGxpc3QoKQoKbm0gPSAxNQpmb3Ioc3R1ZHlubSBpbiBuYW1lcyhtb2QzYmV0YXMpKXsKICAKICBiZXRhcyA9IG1vZDNiZXRhc1tbc3R1ZHlubV1dWzE6MTVdCiAgbm1zID0gbmFtZXMoYmV0YXMpCiAgZHQgPSBkYXRhLnRhYmxlKGNvZWY9bm1zLCBiZXRhcywgc3R1ZHk9c3R1ZHlubSkKICB0bXBkdFtbc3R1ZHlubV1dID0gZHQKfQoKbW9kM2JldGFzX25ldyA9IGRvLmNhbGwocmJpbmQsIHRtcGR0KQpnZ3Bsb3QobW9kM2JldGFzX25ldykgKyBnZW9tX3BvaW50KGFlcyh4PXN0dWR5LCB5PWJldGFzLCBjb2xvcj1zdHVkeSksIHNpemU9NCkgKyBmYWNldF93cmFwKH5jb2VmLCAgc2NhbGVzPSdmcmVlJykgKyAKICAgICAgICAgICAgICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0PTApKSArIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemU9OCkpCmBgYAoKQSBmZXcgaW50ZXJlc3RpbmcgaW50ZXJhY3RpdmUgZWZmZWN0cywgYnV0IG5vdGhpbmcgY29uc2lzdGVudCBhY3Jvc3MgcG9wdWxhdGlvbnMuICAKCjEuIEluIEZsb3JpZGEgUmFvdWwgYW5kIFR4IFR5bGVyIFcyIHRoZXJlIGlzIGFuIGludGVyYWN0aW9uIGJldHdlZW4gY3JvcF9sb2MgYW5kIG1hc3RpbmdfbG9jLCBzdWNoIHRoYXQgYXMgcGlncyBpbmNyZWFzZSB0aGVpciB0ZW5kZW5jeSB0byBzcGVuZCBtb3JlIHRpbWUgbmVhciBjcm9wcyB0aGV5IGRlY3JlYXNlIHRoZSB0aW1lIHRoZXkgc3BlbmQgaW4gaGlnaCBtYXN0aW5nIGxheWVycy4gCjIuIEZvciBUZWpvbiwgdGhlcmUgaXMgYSBwb3NpdGl2ZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIE5EVkkgYW5kIGNyb3BfbG9jLCBzdWNoIHRoYXQgYXMgYmlncyBpbmNyZWFzZSB0aGVpciB0ZW5kZW5jeSB0byBzcGVuZCBtb3JlIHRpbWUgbmVhciBjcm9wcywgdGhleSBzcGVuZCBsZXNzIHRpbWUgaW4gaGFiaXRhdHMgd2l0aCBoaWdoIE5EVkkuCgpUaGVzZSBpbnRlcmFjdGlvbnMgcHJvYmFibHkgYWxzbyB2YXJ5IHdpdGggdGltZS4gSGF2ZW4ndCBsb29rZWQgYXQgdGhhdCB5ZXQuCgojIyBTdGVwIDQ6IFJlcGxhY2luZyB0aW1lLXZhcnlpbmcgcGFyYW1ldGVycyB3aXRoIHRlbXBlcmF0dXJlLCBwcmVjaXBpdGF0aW9uLCBhbmQgc25vdyBjb3ZlciBpbnRlcmFjdGlvbnMKClRoaXMgd2lsbCBiZSBzaW1pbGFyIHRvIG1vZGVsIDIsIGJ1dCBpbnN0ZWFkIG9mIGJhc2lzIGZ1bmN0aW9ucyB0aGF0IHZhcnkgYnkgbW9udGggKHdlIHdpbGwga2VlcCB0aGUgZGFpbHkgYmFzaXMgZnVuY3Rpb24pLCB3ZSB3aWxsIHJlcGxhY2UgdGhlc2UgZWZmZWN0IGJ5IGludGVyYWN0aW9ucyB3aXRoIHRlbXBlcmF0dXJlIGFuZCBwcmVjaXBpdGF0aW9uLiAgVGhpcyBtb2RlbCBpcyB0cnlpbmcgdG8gZ2V0IGF0IHRoZSBtZWNoYW5pc3RpYyB0aW1lIHZhcnlpbmcgZWZmZWN0cyAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpzb3VyY2UoInBpZ2Z4bnMuUiIpCgphbGxtb2RlbDRfZml0cyA9IGxpc3QoKQphbGxYaW50c19mdWxsID0gbGlzdCgpCgpmb3Ioc3R1ZHlubSBpbiBuYW1lcyhkYXRhc2V0KSl7CiAgCiAgY2F0KCJGaXR0aW5nIiwgc3R1ZHlubSwgIlxuIikKICAKICBkYXQgPSBkYXRhc2V0W1tzdHVkeW5tXV0KICBpbnRlciA9IGJ1aWxkX2Rlc2lnbl9tYXRyaXgoZGF0LCBjKCJjcm9wIiksIG1vZGVsdHlwZSA9ICJmdWxsIikKICBkYXRhc2V0W1tzdHVkeW5tXV0gPSBpbnRlciRkYXRhCiAgZXZhbGZvcm0gPSBpbnRlciRldmFsZm9ybQogIAogIFhnYW0gPSBhbGxYZ2Ftc1tbc3R1ZHlubV1dCiAgWGludCA9IGNiaW5kKG1vZGVsLm1hdHJpeChldmFsZm9ybSwgaW50ZXIkZGF0YSksIFhnYW1bLCBwYXN0ZTAoImhvdXJfIiwgMTooZGZfaG91ciAtMSkpXSkKICBhbGxYaW50c19mdWxsW1tzdHVkeW5tXV0gPSBYaW50CiAgCiAgZml0bW9kZWw0ID0gY3YuZ2xtbmV0KFhpbnQsIHk9ZGF0JHosIG9mZnNldD1sb2coZGF0JHRhdSksIAogICAgICAgICAgICAgICAgICAgIGZhbWlseT0icG9pc3NvbiIsIGFscGhhPTEsIG5sYW1iZGE9MjAsIG5mb2xkcz00LCBwYXJhbGxlbD1UUlVFKQogIGFsbG1vZGVsNF9maXRzW1tzdHVkeW5tXV0gPSBmaXRtb2RlbDQKICAKfQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQptb2Q0YmV0YXMgPSBsaXN0KCkKCmZvcihzdHVkeW5tIGluIG5hbWVzKGFsbG1vZGVsNF9maXRzKSl7CiAgCiAgdGZpdCA9IGFsbG1vZGVsNF9maXRzW1tzdHVkeW5tXV0KICAjcGxvdCh0Zml0KQogIHByaW50KHN0dWR5bm0pCiAgcHJpbnQodGZpdCRnbG1uZXQuZml0JGJldGFbLCB3aGljaCh0Zml0JGxhbWJkYSA9PSB0Zml0JGxhbWJkYS4xc2UpLCBkcm9wPUZdKQogIG1vZDRiZXRhc1tbc3R1ZHlubV1dID0gdGZpdCRnbG1uZXQuZml0JGJldGFbLCB3aGljaCh0Zml0JGxhbWJkYSA9PSB0Zml0JGxhbWJkYS4xc2UpLCBkcm9wPVRdCn0KYGBgCgpgYGB7ciwgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTIwfQp0bXBkdCA9IGxpc3QoKQoKZm9yKHN0dWR5bm0gaW4gbmFtZXMobW9kM2JldGFzKSl7CiAgCiAgYmV0YXMgPSBtb2Q0YmV0YXNbW3N0dWR5bm1dXVsxOjM5XQogIG5tcyA9IG5hbWVzKGJldGFzKQogIGR0ID0gZGF0YS50YWJsZShjb2VmPW5tcywgYmV0YXMsIHN0dWR5PXN0dWR5bm0pCiAgdG1wZHRbW3N0dWR5bm1dXSA9IGR0Cn0KCm1vZDRiZXRhc19uZXcgPSBkby5jYWxsKHJiaW5kLCB0bXBkdCkKZ2dwbG90KG1vZDRiZXRhc19uZXcpICsgZ2VvbV9wb2ludChhZXMoeD1zdHVkeSwgeT1iZXRhcywgY29sb3I9c3R1ZHkpLCBzaXplPTQpICsgZmFjZXRfd3JhcCh+Y29lZiwgIHNjYWxlcz0nZnJlZScpICsgCiAgICAgICAgICAgICAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdD0wKSkgKyB0aGVtZV9idygpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCBzaXplPTgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQpgYGAKCipDb25zaXN0ZW50IEVmZmVjdHMqCgoxLiBBcyB0ZW1wZXJhdHVyZSBpbmNyZWFzZXMsIHRoZXJlIGlzIGFuIGluY3JlYXNlZCB0ZW5kZW5jeSB0byBtb3ZlIHRvd2FyZCBjb3ZlciBmb3IgbW9zdCBzdHVkaWVzLgoyLiBJbmNyZWFzaW5nIHRlbXBlcmF0dXJlIGluY3JlYXNlcyB0aW1lIHNwZW50IGluIGhpZ2ggTkRWSSBjZWxscwozLiBJbmNyZWFzZWQgcHJlY2lwaXRhdGlvbiBhbmQgdGVtcGVyYXR1cmUgZ2VuZXJhbGx5IGluY3JlYXNlcyBvciBoYXMgbm8gZWZmZWN0IG9uIHRpbWUgc3BlbmQgaW4gaGlnaCBtYXN0aW5nIGNlbGxzCjQuIEEgY29uc2lzdGVudCBlZmZlY3QgaW50ZXJhY3Rpb24gYmV0d2VlbiB0ZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbiBvbiB3YXRlciB1c2UuICBOb3QgbXVjaCB0byBzYXkgaGVyZSBvdGhlciB0aGFuIHNlYXNvbmFsaXR5LCBhcyByZWZsZWN0ZWQgYnkgdGhpcyBpbnRlcmFjdGlvbiwgYWZmZWN0IHdhdGVyIHVzZS4KCi0tLQoKUGxvdCB0aGUgdGVtcGVyYXR1cmUsIHByZWNpcGl0YXRpb24sIGFuZCBORFZJIGVmZmVjdHMgb3ZlciAibW9udGggb2YgeWVhciIgdG8gc2VlIGhvdyB0aGVzZSB2YXJpYWJsZXMgYXJlIGNoYW5pbmcgb3ZlciB0aGUgc3R1ZHkgcGVyaW9kLgoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojIFBsb3Qgc3RhbmRhcmRpemVkIHRlbXAsIApmb3Ioc3R1ZHlubSBpbiBuYW1lcyhkYXRhc2V0KSl7CiAgCiAgZGF0ID0gZGF0YXNldFtbc3R1ZHlubV1dCiAgZGF0Wywgc25vd2RlcHRoX2xvY196Oj0gc2NhbGUoc25vd2RlcHRoX2xvYyldCiAgbWVhbnZhbHMgPSBkYXRbLCBsaXN0KG1lYW50ZW1wPW1lYW4odGVtcGVyYXR1cmVfbG9jX3opLCBtZWFucHJlY2lwPW1lYW4ocHJlY2lwaXRhdGlvbl9sb2NfeiksIG1lYW5uZHZpPW1lYW4obmR2aV9sb2NfeiksIG1lYW5zbm93PW1lYW4oc25vd2RlcHRoX2xvY196KSksIGJ5PW1vbnRob2Z5ZWFyXQogIHRwbG90ID0gZ2dwbG90KG1lYW52YWxzKSArIGdlb21fbGluZShhZXMoeD1tb250aG9meWVhciwgeT1tZWFubmR2aSwgY29sb3I9Ik5EVkkiKSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PW1vbnRob2Z5ZWFyLCB5PW1lYW50ZW1wLCBjb2xvcj0iVGVtcGVyYXR1cmUiKSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyh4PW1vbnRob2Z5ZWFyLCB5PW1lYW5wcmVjaXAsIGNvbG9yPSJQcmVjaXBpdGF0aW9uIikpICsgCiAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fbGluZShhZXMoeD1tb250aG9meWVhciwgeT1tZWFuc25vdywgY29sb3I9IlNub3cgZGVwdGgiKSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWVfYncoKSArIHlsYWIoIlN0YW5kYXJkaXplZCB2YWx1ZSIpICsgeGxhYigiTW9udGggb2YgeWVhciIpICsgCiAgICAgICAgICAgICAgICAgICAgICAgIGdndGl0bGUoc3R1ZHlubSkKICBwcmludCh0cGxvdCkKCn0KCmBgYAoKCgotLS0KCiMjIFRPRE86IFBvc3QtaG9jIHBvcHVsYXRpb24tbGV2ZWwgYW5hbHlzZXMKCk9rLCBzbyB3ZSBoYXZlIGVzdGltYXRlZCB0aGUgZWZmZWN0cyBvZiB2YXJpb3VzIGZvcmFnaW5nIHJlc291cmNlcyBvbiBwaWcgbW92ZW1lbnQgYW1vbmcgZGlmZmVyZW50IHBvcHVsYXRpb25zLCBub3cgdGhlIGdvYWwgaXMgdG8gYXNrIHdoYXQgcG9wdWxhdGlvbi1sZXZlbCB2YXJpYWJsZXMgKGF2ZXJhZ2Ugc25vdyBkZXB0aCwgZm9yYWdlIHJlc291cmNlIGhldGVyb2dlbmVpdHksICkgYWZmZWN0IGhvdyBwaWcncyB1c2UgYW50aHJvcG9nZW5pYyBhbmQgbmF0dXJhbCBmb3JhZ2UgcmVzb3VyY2VzLiAgQXJlIHRoZSBjb25zaXN0ZW50IHBvcHVsYXRpb24tbGV2ZWwgb3IgZW52aXJvbm1lbnRhbCBwcmVkaWN0b3JzIHRoYXQgY2FuIGFjY291bnQgZm9yIHZhcmlhdGlvbiBpbiByZXNvdXJjZSB1c2UgYWNyb3NzIHBvcHVsYXRpb25zPyAgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCnN1bWRhdHMgPSBsaXN0KCkKZm9yKHN0dWR5bm0gaW4gbmFtZXMoZGF0YXNldCkpewogIAogIGRhdCA9IGRhdGFzZXRbW3N0dWR5bm1dXQogIHN1bWRhdCA9IGRhdFt6ID09IDEsIGxhcHBseShsaXN0KG5kdmk9bmR2aV9sb2MsIGNyb3A9Y3JvcF9sb2MsIG1hc3Rpbmc9bWFzdGluZ19sb2MsIHdhdGVyPXdhdGVyX2xvYywgZGV2PWRldmVsb3BlZF9sb2MpLCBmdW5jdGlvbih4KSBxdWFudGlsZSh4LCBjKDAuMjUsIDAuNSwgMC43NSkpKV0KICBzdW1kYXQkc3R1ZHkgPSBzdHVkeW5tCiAgc3VtZGF0c1tbc3R1ZHlubV1dID0gc3VtZGF0CiAgCn0KCnN1bWRhdHNkdCA9IGRvLmNhbGwocmJpbmQsIHN1bWRhdHMpCgpgYGAK